package cn.com.qtgl.userfilters.model.pojo;

import cn.com.qtgl.userfilters.model.enums.DepartmentAdapter;
import cn.com.qtgl.userfilters.model.enums.PostAdapter;
import cn.com.qtgl.userfilters.model.enums.UserFilterType;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Getter
public class UserFilters {

    public static final Pattern USER_FILTER_REGEX=Pattern.compile("^(::([0-9a-zA-Z\\-_]+))|(((([0-9a-zA-Z\\-_]+)([*=+]?))|(\\*))?(:((([0-9a-zA-Z\\-_]+)([*=]?))|([*#]?)))?)?$");

    private final List<UserFilter<?extends Triple>> userFilters;

    public UserFilters(List<UserFilter<? extends Triple>> userFilters) {
        this.userFilters = new ArrayList<>(userFilters);
    }
    public UserFilters() {
        this.userFilters=new ArrayList<>(0);
    }

    public UserFilters addUserFilter(UserFilter<? extends Triple> userFilter){
        this.userFilters.add(userFilter);
        return this;
    }
    public List<UserFilter<?extends Triple>> getUserFilters(){
        return new ArrayList<>(this.userFilters);
    }
    public String getBody(){
        return userFilters.stream().map(UserFilter::getBody).collect(Collectors.joining(","));
    }
    public List<String> getBodies(){
        return userFilters.stream().map(UserFilter::getBody).collect(Collectors.toList());
    }

    public static UserFilters parseUserFilters(String bodies){
        return parseUserFilters(bodies,false);
    }

    public static UserFilters parseUserFilters(String bodies,boolean ignoreError){
        return Arrays.stream(bodies.split(",")).reduce(new UserFilters(),(userFilters,body)->{
            if(Objects.equals(body.trim(),"::*")){
                return userFilters.addUserFilter(new UserFilter<>(UserFilterType.USER,AllUser.instance));
            }
            Matcher m=USER_FILTER_REGEX.matcher(body);
            if(m.matches()){
                String user=m.group(2);
                String department=StringUtils.defaultIfBlank(m.group(6),"*");
                String depFlag=StringUtils.defaultIfBlank(m.group(7),"*");
                String post=StringUtils.defaultIfBlank(m.group(12),StringUtils.defaultIfBlank(m.group(14),"*"));
                String postFlag=StringUtils.defaultIfBlank(m.group(13),StringUtils.isBlank(m.group(12))?"":"*");
                if(StringUtils.isNotBlank(m.group(2))){
                    return userFilters.addUserFilter(new UserFilter<>(UserFilterType.USER,new UserItem(user)));
                }else{
                    DepartmentAdapter departmentAdapter=switch (depFlag){
                        case "+"->DepartmentAdapter.BIND;
                        case "="->DepartmentAdapter.EQ;
                        default -> DepartmentAdapter.ALL;
                    };
                    PostAdapter postAdapter=switch (postFlag){
                        case "="->PostAdapter.EQ;
                        default -> PostAdapter.ALL;
                    };
                    return userFilters.addUserFilter(new UserFilter<>(UserFilterType.POSITION,new PositionItem(
                            department,
                            Objects.equals(department,"*")?DepartmentAdapter.NONE:departmentAdapter,
                            post,
                            List.of("*","#").contains(post)?PostAdapter.NONE:postAdapter
                    )));
                }
            }else{
                if(ignoreError) {
                    return userFilters;
                }else{
                    throw new RuntimeException("UserFilter:["+body+"]错误，请检查");
                }
            }
        },(u,b)->null);
    }

    public static boolean validUserFilters(String bodies){
        if(Objects.equals(bodies.trim(),"::*")){
            return true;
        }
        return Arrays.stream(bodies.split(",")).reduce(true,(valid,body)->{
            Matcher m=USER_FILTER_REGEX.matcher(body);
            return valid&&m.matches();
        },(u,b)->null);
    }

    @Override
    public String toString() {
        return getBody();
    }

//    public static void main(String[] args) {
//
////        System.out.println(parseUserFilters("::adfasdf434534asdf,University:Student,abcde:#a",false));
//        System.out.println(parseUserFilters("0404="));
////        System.out.println(parseUserFilters("University+"));
////        System.out.println(parseUserFilters(":Teacher"));
//
//    }
}
